package com.jsj.controller;

import com.jsj.domain.SimSubmission;
import com.jsj.service.impl.SimSubmissionServiceImpl;
import com.jsj.service.impl.SubmissionTopicServiceImpl;
import com.jsj.utils.HammingUtil;
import com.jsj.utils.WordUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

/**
 * 文件查重Controller
 *
 * @author timec
 * @date 2022-08-09
 */
@RestController
@RequestMapping("/sim")
public class SimSubmissionController extends BaseController {

    private SimSubmissionServiceImpl iSimSubmissionService;
    private SubmissionTopicServiceImpl submissionTopicService;

    @Autowired
    public void setiSimSubmissionService(SimSubmissionServiceImpl iSimSubmissionService) {
        this.iSimSubmissionService = iSimSubmissionService;
    }

    @Autowired
    public void setSubmissionTopicService(SubmissionTopicServiceImpl submissionTopicService) {
        this.submissionTopicService = submissionTopicService;
    }

    /**
     * SimHash查重
     */
    @PostMapping("/simFile")
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public AjaxResult simFile(@RequestBody SimSubmission simSubmission) throws Exception {
        try {
            File file1 = new File(simSubmission.getFilePath());
            FileInputStream fileInputStream = new FileInputStream(file1);
            MultipartFile file = new MockMultipartFile(simSubmission.getFileName(), file1.getName(), "text/plain", IOUtils.toByteArray(fileInputStream));
            //获取SimHash值
            String msgSimHash = WordUtil.getSimHash(file);
            simSubmission.setSimHash(msgSimHash);
            //查询所属分组的所有文件SimHash值
            List<SimSubmission> list = iSimSubmissionService.query(simSubmission.getSubTopId(), simSubmission.getProblemId());
            if (list.size() == 1) {
                iSimSubmissionService.updateSimSubmission(simSubmission);
                return AjaxResult.success("首次提交豁免");
            }
            //最大相似度
            double similarity = 0;
            int subTopId = 0;
            // TODO: 2022/8/9 第一次提交，集合为空
            for (SimSubmission tF : list) {
                if (tF.getSimHash() != null) {
                    if (similarity < HammingUtil.getSimilarity(msgSimHash, tF.getSimHash())) {
                        similarity = HammingUtil.getSimilarity(msgSimHash, tF.getSimHash());
                        subTopId = tF.getSubTopId();
                    }
                }
            }
            //查重信息
            String msg = "";
            if (similarity > 0.7) {
                // TODO: 2022/7/31 前端提示：未通过查重
                msg = "未通过查重，相似度为：" + similarity + "大于70%";
            } else {
                msg = "恭喜你，已通过查重，相似度为：" + similarity + "小于70%";
                //本地保存文件
                // TODO: 2022/7/31 group=课程名称+作业名称，前缀需要考虑
                String group = "";
                // TODO: 2022/7/31 异常处理：文件已存在
//                WordUtil.saveFile(file, group);
                //文件信息入数据库
              /*  SimSubmission bcSimSubmission = new SimSubmission();
                bcSimSubmission.setSubTopId(1);
                bcSimSubmission.setProblemId(1);
                bcSimSubmission.setFileName(file.getOriginalFilename());
                bcSimSubmission.setFilePath(WordUtil.getPath(group));
                bcSimSubmission.setSimHash(msgSimHash);
                bcSimSubmission.setTargetId("1");*/

                //将double类型转为数据库存储中的Integer类型
                double aDouble = Double.valueOf(similarity);
                short val = (short) (aDouble * 100);
                simSubmission.setSimilarity(val);
                simSubmission.setTargetId(submissionTopicService.querySubmissionTopicById(subTopId).getUserId());
                iSimSubmissionService.updateSimSubmission(simSubmission);
            }
            System.out.println(msg);
            AjaxResult ajax = AjaxResult.success();
            ajax.put("msg", msg);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 查询文件查重列表
     */
    @PostMapping("/query")
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public TableDataInfo query(@RequestBody int[] i) {
        startPage();
        List<SimSubmission> list = iSimSubmissionService.query(i[0], i[1]);
        return getDataTable(list);
    }

    /**
     * 导出文件查重列表
     */
   /* @Log(title = "文件查重", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SimSubmission simSubmission) {
        List<SimSubmission> list = iSimSubmissionService.query(jobSubmission);
        ExcelUtil<JobSubmission> util = new ExcelUtil<JobSubmission>(JobSubmission.class);
        util.exportExcel(response, list, "文件查重数据");
    }*/

    /**
     * 获取文件查重详细信息
     */
  /*  @GetMapping(value = "/queryById")
    public AjaxResult getInfo(long id) {
        return AjaxResult.success(iSimSubmissionService.queryById(id));
    }*/

    /**
     * 新增文件查重
     */
   /* @Log(title = "文件查重", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SimSubmission simSubmission) {
        return toAjax(iSimSubmissionService.insertSimSubmission(simSubmission));
    }*/

    /**
     * 修改文件查重
     */
  /*  @Log(title = "文件查重", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SimSubmission simSubmission) {
        return toAjax(iSimSubmissionService.updateSimSubmission(simSubmission));
    }*/

    /**
     * 删除文件查重
     */
  /*  @Log(title = "文件查重", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable long[] ids) {
        return toAjax(iSimSubmissionService.deleteSimSubmissionByIds(ids));
    }*/

}
